/*************************************************************************
 *                                                                       *
 * This file is part of the FreeMAPs distribution.  For full copyright   *
 * information, see COPYRIGHT and COPYING.LESSER.                        *
 *                                                                       *
 * Author:           sqbang                                              *
 * Email:            sqbang@ustc.edu                                     *
 * Date:             2016.03.24                                          *
 *                                                                       *
 *************************************************************************/

//declaration header
#include "COMMON/bdry/ThermalStressLoadBoundaryCondition.h"

//COMMON headers
#include "COMMON/equa/PDEEquationEnsembleStrategy.h"
#include "COMMON/equa/EquationDomain.h"
#include "COMMON/info/InfoManager.h"
#include "COMMON/info/CommonInfo.h"
#ifdef FREEMAPS_HAVE_SAMRAI
#include "COMMON/regn/Region.h"
#endif
#include "COMMON/tbox/LogMessage.h"
#include "COMMON/tbox/Utilities.h"



namespace FreeMAPs
{

ThermalStressLoadBoundaryCondition::ThermalStressLoadBoundaryCondition (
    const std::string& parent_name,
    const std::string& bc_name,
    const PDEEquationEnsembleStrategy* equation_ensemble) :
    Parent (parent_name, bc_name, equation_ensemble),
//    d_para_init_temperature(300)
    d_para_init_temperature("300")
{}



ThermalStressLoadBoundaryCondition::~ThermalStressLoadBoundaryCondition ()
{
    this->clear();
}



void
ThermalStressLoadBoundaryCondition::clear()
{
//    Utilities::clear_pointer_object (d_para_temperature);
//    Utilities::clear_pointer_object (d_para_init_temperature);
}



void
ThermalStressLoadBoundaryCondition::set_para_init_temperature(
        const std::string& para_init_temperature)
{
    d_para_init_temperature = para_init_temperature;
}



const std::string&
ThermalStressLoadBoundaryCondition::get_para_init_temperature()
{
    return d_para_init_temperature;
}



void
ThermalStressLoadBoundaryCondition::get_from_input (
    const InputDatabase* db)
{
#if 0
    this->prepare_for_use (db);

    db->insert_allowable_key ("bc_type");
#ifdef FREEMAPS_HAVE_SAMRAI
    db->insert_allowable_key ("act_type");
    db->insert_allowable_key ("discrete_parameters");
#endif
    db->insert_allowable_key ("physical_parameters");

    if (this->require_set_variable())
    {
        db->insert_allowable_key ("variable_symbol");
    }

    db->check_allowable_keys();
#ifdef FREEMAPS_HAVE_SAMRAI
    /*
     * the boundary_condition_type will be read before the boundary condition is build.
     * so do NOT read it here.
     */
    const bool act_on_structured_mesh = d_equation_ensemble->get_equation_domain()->get_region()->use_structured_mesh();
    /*
     * build act_type
     */
    if (act_on_structured_mesh)
    {
        db->check_optional_key ("act_type", DataType::STRING, true, false);
        d_act_type = db->get_enum_with_default ("act_type", d_act_type);
    }
    else
    {
        db->check_disallowable_key ("act_type", "it only work when act_on_structured_mesh");
    }
#endif

    /*
     * build discrete_parameters.
     * note that discrete_parameters should be build before boundary_condition_parameters.
     * because some boundary_condition_parameters should be checked corresponding to discrete_parameters.
     */
#ifdef FREEMAPS_HAVE_SAMRAI
    if (act_on_structured_mesh)
    {
        db->check_requisite_database ("discrete_parameters");
        d_discrete_parameters.get_from_input (db->get_database ("discrete_parameters"));
    }
    else
    {
        db->check_disallowable_key ("discrete_parameters", "it only work when act_on_structured_mesh");
    }
#endif

    /*
     * build physical_parameters
     */
    {
        db->check_requisite_key ("physical_parameters", DataType::DATABASE, false, false);
        this->get_info_for_derived_object_from_input (db->get_database ("physical_parameters"));
    }
#endif
}



void
ThermalStressLoadBoundaryCondition::get_info_for_derived_object_from_input (
    const InputDatabase* db)
{
#if 0
    this->prepare_for_use (db);

    db->insert_allowable_key ("para_temperature");
    db->insert_allowable_key ("para_init_temperature");

    db->check_allowable_keys();

    d_para_temperature = new Function (this->get_full_name(), "para_temperature");
    db->check_requisite_key ("para_temperature", DataType::UNKNOWN, false, false);
        d_para_temperature->get_from_input (db, "para_temperature",InfoManager::get_instance()->get_variable_info(),
            InfoManager::get_instance()->get_function_info());
        d_para_temperature->attach_region (this->get_equation_ensemble()->get_equation_domain()->get_region());
        d_para_temperature->set_used_flag();
 
	d_para_init_temperature = new Function (this->get_full_name(), "para_init_temperature");
	db->check_requisite_key ("para_init_temperature", DataType::UNKNOWN, false, false);
        d_para_init_temperature->get_from_input (db, "para_init_temperature",InfoManager::get_instance()->get_variable_info(),
            InfoManager::get_instance()->get_function_info());

        d_para_init_temperature->attach_region (this->get_equation_ensemble()->get_equation_domain()->get_region());
        d_para_init_temperature->set_used_flag();
#endif
}



std::string
ThermalStressLoadBoundaryCondition::get_info_from_derived_object() const
{
    std::ostringstream os, oss;

    os << "physical_parameters\n{";

//    oss << '\n' << *d_para_init_temperature;
//    oss << '\n' << *d_para_temperature;

    oss << '\n' << "para_temperature = " << "\"T\"";
    oss << '\n' << "para_init_temperature = " << d_para_init_temperature;

    os << LogMessage::get_log_info (oss, ONE_TAB) << '\n';
    os << "}";

    return os.str();
}

} // namespace FreeMAPs
